package org.easy.socket.client.processor;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import org.easy.socket.client.model.DataModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.smartboot.socket.StateMachineEnum;
import org.smartboot.socket.extension.processor.AbstractMessageProcessor;
import org.smartboot.socket.transport.AioSession;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
 * @Description: 客户端数据
 * @Author: wxl
 * @CreateTime: 2023/1/16 14:37
 */
public class EasyClientMessageProcessor extends AbstractMessageProcessor<String> {

    private static final Logger logger = LoggerFactory.getLogger(EasyClientMessageProcessor.class);

    private final List<String> sendFailDataList = new LinkedList<>();

    private final DataModel dataModel;

    private AioSession session;

    public EasyClientMessageProcessor () {
        this.dataModel = new DataModel();
    }

    @Override
    public void process0(AioSession aioSession, String s) {
        logger.info("于[{}]从服务器端收到的信息:{}", DateUtil.now(),s);
        JSONObject object = JSONObject.parseObject(s);
        if (object.containsKey("state")) {
            String clientId = object.getString("clientId");
            this.dataModel.setClientId(clientId);
        }
    }

    @Override
    public void stateEvent0(AioSession session, StateMachineEnum stateMachineEnum, Throwable throwable) {
        switch (stateMachineEnum) {
            case NEW_SESSION:
                if (Objects.isNull(this.session)) {
                    this.session = session;
                }
                break;
            case SESSION_CLOSED:
            case PROCESS_EXCEPTION:
            case DECODE_EXCEPTION:
            case INPUT_EXCEPTION:
            case OUTPUT_EXCEPTION:
            case INPUT_SHUTDOWN:
                logger.info("异常: {}", session.toString());
                break;
            default:
        }
    }

    public void sendToServer (String data) {
        if (Objects.nonNull(data)) {
            this.dataModel.setData(data);
            if (Objects.nonNull(this.session)) {
                try{
                    this.session.writeBuffer().writeInt(getDataBytes().length);
                    this.session.writeBuffer().write(getDataBytes());
                    this.session.writeBuffer().flush();
                } catch (IOException e) {
                    addFailDataToList(data);
                    logger.error("发送消息出现异常:{}",e.getMessage());
                }
            } else {
                logger.info("请求先连接服务端再向服务端发送消息......");
            }
        }
    }

    public DataModel getDataModel() {
        return dataModel;
    }

    private byte[] getDataBytes () {
        String data = JSONObject.toJSONString(getDataModel());
        return data.getBytes(StandardCharsets.UTF_8);
    }

    private synchronized void addFailDataToList (String data) {
        synchronized (this) {
            getSendFailDataList().add(data);
        }
    }

    public List<String> getSendFailDataList() {
        return sendFailDataList;
    }
}
